<template>
  <div class="json-node-editor">
    <!-- 工具栏 -->
    <div class="editor-toolbar">
      <el-button-group>
        <el-button size="small" @click="autoLayout">
          <el-icon><Position /></el-icon>
          自动布局
        </el-button>
        <el-button size="small" @click="zoomToFit">
          <el-icon><ZoomIn /></el-icon>
          适应画布
        </el-button>
      </el-button-group>
    </div>

    <!-- 节点画布 -->
    <div class="editor-canvas">
      <vue-flow
        v-model="elements"
        :default-viewport="{ zoom: 1 }"
        :fit-view-on-init="true"
        class="workflow-canvas"
      >
        <!-- 背景 -->
        <background pattern-color="#aaa" gap="8" />
        
        <!-- 控制器 -->
        <controls />
        
        <!-- 小地图 -->
        <minimap />
        
        <!-- 自定义节点 -->
        <template #node-custom="nodeProps">
          <workflow-node v-bind="nodeProps" @edit="editNode" />
        </template>
      </vue-flow>
    </div>

    <!-- 节点编辑对话框 -->
    <el-dialog
      v-model="editDialog.visible"
      :title="editDialog.title"
      width="600px"
    >
      <div class="node-params">
        <div
          v-for="(value, key) in editDialog.node?.inputs"
          :key="key"
          class="param-item"
        >
          <div class="param-label">{{ formatParamLabel(key) }}</div>
          <div class="param-editor">
            <!-- 数字类型 -->
            <el-input-number
              v-if="typeof value === 'number'"
              v-model="editDialog.node!.inputs[key]"
              :step="1"
              @change="handleNodeChange"
            />
            <!-- 布尔类型 -->
            <el-switch
              v-else-if="typeof value === 'boolean'"
              v-model="editDialog.node!.inputs[key]"
              @change="handleNodeChange"
            />
            <!-- 选择类型 -->
            <el-select
              v-else-if="Array.isArray(value)"
              v-model="editDialog.node!.inputs[key]"
              @change="handleNodeChange"
            >
              <el-option
                v-for="(opt, index) in value"
                :key="index"
                :label="opt"
                :value="opt"
              />
            </el-select>
            <!-- 文本类型 -->
            <el-input
              v-else
              v-model="editDialog.node!.inputs[key]"
              @change="handleNodeChange"
            />
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Position, ZoomIn } from '@element-plus/icons-vue'
import {
  VueFlow,
  Background,
  Controls,
  MiniMap,
  useVueFlow
} from '@vue-flow/core'
import type { Node, Edge } from '@vue-flow/core'
import WorkflowNode from './nodes/WorkflowNode.vue'

const props = defineProps<{
  modelValue: string
}>()

const emit = defineEmits(['update:modelValue'])

// Vue Flow 实例
const { onNodeClick, onConnect, onEdgesChange, onNodesChange } = useVueFlow()

// 编辑对话框
const editDialog = ref({
  visible: false,
  title: '',
  node: null as any
})

// 转换节点数据
const transformNodes = (nodes: Record<string, any>): Node[] => {
  return Object.entries(nodes).map(([id, node]) => ({
    id,
    type: 'custom',
    position: node.position || { x: 0, y: 0 },
    data: {
      ...node,
      label: node.class_type || '节点'
    }
  }))
}

// 转换连接数据
const transformEdges = (nodes: Record<string, any>): Edge[] => {
  const edges: Edge[] = []
  Object.entries(nodes).forEach(([id, node]) => {
    if (node.inputs) {
      Object.entries(node.inputs).forEach(([key, value]) => {
        if (typeof value === 'object' && value !== null) {
          edges.push({
            id: `e_${id}_${key}`,
            source: value.node as string,
            target: id,
            animated: true
          })
        }
      })
    }
  })
  return edges
}

// 流程图元素
const elements = computed(() => {
  try {
    const workflow = JSON.parse(props.modelValue)
    return {
      nodes: transformNodes(workflow.nodes || {}),
      edges: transformEdges(workflow.nodes || {})
    }
  } catch (error) {
    console.error('Failed to parse workflow:', error)
    return { nodes: [], edges: [] }
  }
})

// 监听节点点击
onNodeClick(({ node }) => {
  editDialog.value = {
    visible: true,
    title: `编辑节点: ${node.data.class_type || '节点'}`,
    node: node.data
  }
})

// 处理节点变更
const handleNodeChange = () => {
  updateWorkflow()
}

// 更新工作流
const updateWorkflow = () => {
  try {
    const workflow = {
      nodes: Object.fromEntries(
        elements.value.nodes.map(node => [node.id, node.data])
      ),
      version: '1.0.0'
    }
    emit('update:modelValue', JSON.stringify(workflow, null, 2))
  } catch (error) {
    console.error('Failed to update workflow:', error)
  }
}

// 自动布局
const autoLayout = () => {
  // TODO: 实现自动布局算法
  ElMessage.success('自动布局完成')
}

// 适应画布
const zoomToFit = () => {
  // TODO: 实现画布缩放
  ElMessage.success('已适应画布')
}

// 格式化参数标签
const formatParamLabel = (key: string): string => {
  return key
    .split('_')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
    .join(' ')
}
</script>

<style scoped lang="scss">
.json-node-editor {
  height: 600px;
  display: flex;
  flex-direction: column;

  .editor-toolbar {
    padding: 8px;
    border-bottom: 1px solid #ddd;
  }

  .editor-canvas {
    flex: 1;
    background: #f5f5f5;
    position: relative;

    .workflow-canvas {
      width: 100%;
      height: 100%;
    }
  }

  .node-params {
    .param-item {
      display: flex;
      align-items: center;
      margin-bottom: 12px;

      .param-label {
        width: 150px;
        padding-right: 12px;
        color: #666;
      }

      .param-editor {
        flex: 1;
      }
    }
  }
}
</style> 